package cn.spream.jstudy.ssi.common;

import com.opensymphony.xwork2.util.logging.Logger;
import com.opensymphony.xwork2.util.logging.LoggerFactory;
import org.apache.commons.lang.StringUtils;

import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by IntelliJ IDEA.
 * User: sjx
 * Date: 13-5-31
 * Time: 上午9:50
 * To change this template use File | Settings | File Templates.
 */
public class SSIUrl {

    private static final Logger log = LoggerFactory.getLogger(SSIUrl.class);

    //协议
    private String protocol = "http";

    //端口
    private int port = -1;

    //地址
    private String host;

    //目标
    private String path;
    
    //查询参数
    private Map<String, Object> query = new LinkedHashMap<String, Object>();

    //编码
    private String charset = "UTF-8";

    private boolean filter = true;

    public String render(){
        String urlStr = "";
        URL url = null;
        try {
            url = new URL(protocol, host, port, path);
            if (url.getDefaultPort() == url.getPort()) {
                url = new URL(protocol, host, -1, path);
            }
            urlStr = url.toString();
        } catch (Exception e) {
            urlStr = "/";
        }

        StringBuilder builder = new StringBuilder(urlStr);
        if (!query.isEmpty()) {
            for (String key : query.keySet()) {
                Object obj = query.get(key);
                if (obj instanceof List) {
                    List list = (List) obj;
                    for (Object o : list) {
                        setValue(builder, key, o);
                    }
                } else if (obj instanceof Map) {
                    Map map = (Map) obj;
                    for (Object o : map.keySet()) {
                        setValue(builder, o == null ? "" : o.toString(), map.get(o));
                    }
                } else {
                    if (obj != null && obj.getClass().isArray()) {
                        Object[] arrays = (Object[]) obj;
                        for (Object o : arrays) {
                            setValue(builder, key, o);
                        }
                    } else {
                        setValue(builder, key, obj);
                    }
                }
            }
            return builder.replace(urlStr.length(), urlStr.length() + 1, "?").toString();
        } else {
            return urlStr;
        }
    }

    public void setValue(StringBuilder builder, String key, Object o) {
        String value = o == null ? "" : o.toString();
        if (value.length() > 0) {
            String str1;
            str1 = encodeUrl(value);
            builder.append("&").append(key).append("=").append(str1);
        } else {
            if (!filter) {
                builder.append("&").append(key).append("=");
            }
        }
    }

    public void reset() {
        try {
            query.clear();
        } catch (Exception e) {
            log.error("reset error!", e);
        }
    }

    public String encodeUrl(String value) {
        String str1;
        if (StringUtils.isNotBlank(charset)) {
            try {
                str1 = URLEncoder.encode(value, charset);
            } catch (UnsupportedEncodingException e) {
                str1 = value;
            }
        } else {
            str1 = URLEncoder.encode(value);
        }
        return str1;
    }

    public String toString() {
        String url = render();
        reset();
        return url;
    }

    public SSIUrl getTarget(String target){
        this.path = target;
        return this;
    }

    public SSIUrl addQueryData(String name, Object value) {
        query.put(name, value);
        return this;
    }

    public SSIUrl addQueryData(String name, int value) {
        query.put(name, value);
        return this;
    }

    public SSIUrl addQueryData(String name, long value) {
        query.put(name, value);
        return this;
    }

    public SSIUrl addQueryData(String name, float value) {
        query.put(name, value);
        return this;
    }

    public SSIUrl addQueryData(String name, String value) {
        query.put(name, value);
        return this;
    }

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }
}
